package com.se.frontline.gameplay;

import java.util.LinkedList;
import java.util.List;

import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.entity.IEntity;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.shape.IShape;
import org.andengine.input.sensor.acceleration.AccelerationData;
import org.andengine.input.sensor.acceleration.IAccelerationListener;
import org.andengine.input.touch.TouchEvent;
import org.andengine.input.touch.detector.PinchZoomDetector;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

import com.se.frontline.ManagedScene;
import com.se.frontline.UserData;
import com.se.frontline.gameplay.units.Unit;
import com.se.frontline.gameplay.units.Unit1;
import com.se.frontline.gameplay.units.Unit2;
import com.se.frontline.gameplay.units.Unit3;
import com.se.frontline.layers.FrontlineHUD;
import com.se.frontline.managers.GameManager;
import com.se.frontline.managers.ResourceManager;

public class ManagedGameScene extends ManagedScene implements
		IOnSceneTouchListener, SensorEventListener {

	private static final float MAP_MOVE_GRAVITY_LIMIT = 0.6f;
	private static final float MAP_MOVE_SPEED = 100;
	private static final float RELATIVE_TOP_SPAWNING_BORDER = 0.4f;
	private static final float RELATIVE_BOTTOM_SPAWNING_BORDER = 0.65f;
	private static final float RELATIVE_BACKGROUND_HEIGHT = 0.35f;
	public SensorManager mSensorManager;
	public Sensor mGravitySensor;
	private float currentGravityX;
	public Unit newUnit;
	private List<IEntity> UnitEntities;

	public void load() {
		this.setOnSceneTouchListener(this);
		this.UnitEntities = new LinkedList<IEntity>();
		
		mSensorManager = ResourceManager.getInstance().getActivity().mSensorManager;
		mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
		mSensorManager.registerListener(this, mGravitySensor,
				SensorManager.SENSOR_DELAY_NORMAL);
	}

	@Override
	public Scene onLoadingScreenLoadAndShown() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onLoadingScreenUnloadAndHidden() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onLoadScene() {
		// TODO Auto-generated method stub
		UnitEntities.add(ResourceManager.getInstance().getGameGround().getChildByIndex(0));

	}

	@Override
	public void onShowScene() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onHideScene() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onUnloadScene() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	@Override
	public void onSensorChanged(SensorEvent event) {

		synchronized (this) {

			// This Code gets the needed Information from the Sensor: the
			// strength of gravity along the x axis
			switch (event.sensor.getType()) {
			case Sensor.TYPE_GRAVITY:
				currentGravityX = (float) event.values[1];
				break;
			}

			// If the gravity strength reaches a limit, the camera sets its
			// center to the edge of the map and moves according to gravity
			// strength,
			// if the gravity falls below the limit, the cameras current
			// position is set as its center
			if (currentGravityX > MAP_MOVE_GRAVITY_LIMIT
					|| currentGravityX < (MAP_MOVE_GRAVITY_LIMIT * -1)) {
				ResourceManager.getInstance().getCamera()
						.setMaxVelocityX(currentGravityX * MAP_MOVE_SPEED);
				ResourceManager
						.getInstance()
						.getCamera()
						.setCenter(
								ResourceManager.getInstance().getCamera()
										.getBoundsXMax(),
								(float) (ResourceManager.getInstance().cameraHeight * 0.5));
			} else {
				ResourceManager
						.getInstance()
						.getCamera()
						.setCenter(
								ResourceManager.getInstance().getCamera()
										.getCenterX(),
								ResourceManager.getInstance().getCamera()
										.getCenterY());
			}
		}

	}

	@Override
	public boolean onSceneTouchEvent(Scene arg0, TouchEvent pSceneTouchEvent) {
		if (pSceneTouchEvent.isActionDown()) {

			// Checks if the TouchEvent took place in the right unit area and
			// spawns the unit
			if (pSceneTouchEvent.getY() > (float) (ResourceManager
					.getInstance().cameraHeight * RELATIVE_TOP_SPAWNING_BORDER)
					&& pSceneTouchEvent.getY() < (float) (ResourceManager
							.getInstance().cameraHeight * RELATIVE_BOTTOM_SPAWNING_BORDER)) {
				newUnit = null;
				switch (GameManager.getInstance().getSelectedUnit()) {
				case 0:
					if (FrontlineHUD.InnerFoodBar.getWidth() > 0)
						newUnit = new Unit1(false);
					break;
				case 1:
					if (FrontlineHUD.InnerFoodBar.getWidth() > 0)
						newUnit = new Unit1(true);
					break;
				case 2:
					if (FrontlineHUD.InnerFoodBar.getWidth() > 0)
						newUnit = new Unit1(false);
					break;
				case 3:
					if (FrontlineHUD.InnerFoodBar.getWidth() > 0)
						newUnit = new Unit1(false);
					break;
				case 4:
					if (FrontlineHUD.InnerFoodBar.getWidth() > 0)
						newUnit = new Unit3(true);
					break;
				case 5:
					if (FrontlineHUD.InnerFoodBar.getWidth() > 0)
						newUnit = new Unit3(true);
					break;
				case 6:
					if (FrontlineHUD.InnerFoodBar.getWidth() > 0)
						newUnit = new Unit3(true);
					break;
				default:
					break;
				}

				if (newUnit != null) {

					IUpdateHandler IUH = new IUpdateHandler() {
						@Override
						public void onUpdate(float pSecondsElapsed) {
							for (IEntity unit: UnitEntities)
							{
								if((newUnit.getSprite().collidesWith((IShape) unit)) && newUnit.getSprite() != unit)
								{
									newUnit.fight((Unit)unit.getUserData());
									((Unit) unit.getUserData()).fight(newUnit);
								}
							}
						}

						@Override
						public void reset() {
							// TODO Auto-generated method stub

						};
					};

					newUnit.getSprite().registerUpdateHandler(IUH);

					newUnit.go((float) (pSceneTouchEvent.getY()
							- (float) (ResourceManager.getInstance().cameraHeight * RELATIVE_BACKGROUND_HEIGHT) - ((float) newUnit
							.getHeight() * 1)), (Unit) newUnit);
					UnitEntities.add(ResourceManager.getInstance().getGameGround().getLastChild());
					FrontlineHUD.decreaseFoodBar(30);
				}
			}
		}

		return false;
	}

}
